﻿using System;
using System.Reflection;

namespace Facebook
{
    [AttributeUsage(AttributeTargets.Parameter)]
    public class FacebookMethodParameterAttribute : Attribute
    {
        public FacebookMethodParameterAttribute()
        {
            this.Requirements = RequiredParameterFlags.RequiredDesktop | RequiredParameterFlags.RequiredWebsite;
        }

        public FacebookMethodParameterAttribute(String parameterName, params String[] validValues)
        {
            this.Requirements = RequiredParameterFlags.RequiredDesktop | RequiredParameterFlags.RequiredWebsite;
            this.ParameterName = parameterName;
            this.ValidValues = validValues;
        }

        public FacebookMethodParameterAttribute(String parameterName, RequiredParameterFlags requirements, params String[] validValues)
        {
            this.ParameterName = parameterName;
            this.Requirements = requirements;
            this.ValidValues = validValues;
        }

        public String ParameterName { get; set; }
        public RequiredParameterFlags Requirements { get; set; }
        public String[] ValidValues { get; set; }

        public Boolean EvaluateValueIsValid(ApplicationType appType, PropertyInfo propInfo, Object target)
        {
            Object value;
            Exception ex;
            return this.EvaluateValueIsValid(appType, propInfo, target, out value, out ex);
        }

        public Boolean EvaluateValueIsValid(ApplicationType appType, PropertyInfo propInfo, Object target, out Object value, out Exception ex)
        {
            Boolean isValueValid = false;
            ex = null;
            value = null;

            if ((this.Requirements == RequiredParameterFlags.RequiredDesktop && appType == ApplicationType.Desktop) ||
                (this.Requirements == RequiredParameterFlags.RequiredWebsite && appType == ApplicationType.Website))
            {
                value = propInfo.GetValue(target, null);
                String strValue = Convert.ToString(value);
                
                if (String.IsNullOrEmpty(strValue))
                {
                    ex = new FacebookInvalidParameterException("{0}.{1} must have a value.", propInfo.DeclaringType.Name, propInfo.Name);
                    return false;
                }
            }

            if (this.ValidValues != null && this.ValidValues.Length > 0)
            {
                if(value == null) value = propInfo.GetValue(target, null);
                foreach (var validValue in this.ValidValues)
                {
                    if (validValue.CompareTo(value) == 0)
                    {
                        isValueValid = true;
                        break;
                    }
                }

                if (!isValueValid)
                {
                    ex = new FacebookInvalidParameterException("{0} is not a valid value for {1}.{2}.", value, propInfo.DeclaringType.Name, propInfo.Name);
                    return false;
                }
            }

            return true;
        }
    }
}